package com.nmf.site.biz.sms.bx.service;

import java.util.Date;
import java.util.Random;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.nmf.pc.enums.RspStatus;
import com.nmf.pc.vo.McSmsReq;
import com.nmf.pc.vo.ReturnResult;
import com.nmf.pc.vo.SmsCodeReq;
import com.nmf.site.biz.sms.bx.enums.SmsType;
import com.nmf.site.biz.sms.gen.entity.BizSms;
import com.nmf.site.biz.sms.gen.service.BizSmsService;
import com.nmf.site.common.excep.KideException;
import com.nmf.site.common.excep.KideExpCode;
import com.nmf.site.common.persistence.Page;

@Component
public class SmsCodeService {
	Logger log = LoggerFactory.getLogger(SmsCodeService.class);
	@Autowired
	BizSmsService bizSmsService;

	private int codeTime = 1 * 60 * 1000;// code有效期 1分钟

	@Transactional
	public ReturnResult sendMobileSms(McSmsReq mcSmsReq) {
		ReturnResult returnResult = new ReturnResult();
		// 组装请求对象
		SendSmsRequest request = new SendSmsRequest();
		// 必填:待发送手机号。支持以逗号分隔的形式进行批量调用，批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
		request.setPhoneNumbers(mcSmsReq.getTelNo());
		// 必填:短信模板-可在短信控制台中找到
		SmsType smsType = SmsType.pcYujinSms;
		request.setTemplateCode("SMS_130923039");
		//您好，您编号${mid}的矿机${act}。${dateStr} 请及时关注！
		request.setTemplateParam("{\"mid\":\"" + mcSmsReq.getMid() + "\",\"act\":\""+mcSmsReq.getAct()+"\",\"dateStr\":\""+mcSmsReq.getDateStr()+"\"}");
		SendSmsResponse sendSmsResponse = sendSms(request);
		if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
			// 请求成功
			saveSmsInfo(mcSmsReq.getMid(), sendSmsResponse, smsType, mcSmsReq.getTelNo());
			
		} else {
			returnResult.setStatus(RspStatus.FAILED.value);
			returnResult.setMessage("【短信发送失败】");
			log.error("【短信发送失败】" + JSON.toJSONString(sendSmsResponse));
		}
		return returnResult;
	}

	@Transactional
	public String sendMobileCode(SmsCodeReq smsCodeReq) {

		String dbCode = getCode(smsCodeReq.getTelNo());
		if (StringUtils.isNotBlank(dbCode) && !"null".equals(dbCode.toLowerCase())) {
			return dbCode;
		}
		String code = getCodeRandom();
		// 组装请求对象
		SendSmsRequest request = new SendSmsRequest();
		// 必填:待发送手机号。支持以逗号分隔的形式进行批量调用，批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
		request.setPhoneNumbers(smsCodeReq.getTelNo());
		// 必填:短信模板-可在短信控制台中找到
		SmsType smsType = SmsType.getStatus(smsCodeReq.getSmsType());
		if (SmsType.memeberRegisterCode.equals(smsType)) {
			request.setTemplateCode("SMS_129749802");
			request.setTemplateParam("{\"code\":\"" + code + "\"}");
		} else if (SmsType.memberResetPswCode.equals(smsType)) {
			request.setTemplateCode("SMS_130760098");
			request.setTemplateParam("{\"code\":\"" + code + "\"}");
		} else if (SmsType.memberLoginCode.equals(smsType)) {
			request.setTemplateCode("SMS_153700019");
			request.setTemplateParam("{\"code\":\"" + code + "\"}");
		}
		SendSmsResponse sendSmsResponse = sendSms(request);
		if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {
			// 请求成功
			saveSmsInfo(code, sendSmsResponse, smsType, smsCodeReq.getTelNo());
			return code;
		} else {
			log.error("【短信发送失败】" + JSON.toJSONString(sendSmsResponse));
		}
		return null;
	}

	private void saveSmsInfo(String code, SendSmsResponse sendSmsResponse, SmsType smsType, String telNo) {
		// 请求成功
		BizSms bizSms = new BizSms();
		Date date = new Date();
		bizSms.setCode(code.toLowerCase());
		bizSms.setCreateDate(date);
		bizSms.setIsNewRecord(true);
		// bizSms.setReqStr(JSON.toJSONString(request));
		bizSms.setRspStr(JSON.toJSONString(sendSmsResponse));
		bizSms.setSmsType(smsType.value + "");
		bizSms.setTelNo(telNo);
		bizSms.setUpdateDate(date);
		bizSmsService.save(bizSms);
	}

	private SendSmsResponse sendSms(SendSmsRequest request) {
		try {
			// 设置超时时间-可自行调整
			System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
			System.setProperty("sun.net.client.defaultReadTimeout", "10000");
			// 初始化ascClient需要的几个参数
			final String product = "Dysmsapi";// 短信API产品名称（短信产品名固定，无需修改）
			final String domain = "dysmsapi.aliyuncs.com";// 短信API产品域名（接口地址固定，无需修改）
			// 替换成你的AK
			final String accessKeyId = "LTAIHrhESmpC4ihc";// 你的accessKeyId,参考本文档步骤2
			final String accessKeySecret = "vgoO4LF64pdqmdB0TdN6pyaN70vkvv";// 你的accessKeySecret，参考本文档步骤2
			// 初始化ascClient,暂时不支持多region（请勿修改）
			IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
			DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
			IAcsClient acsClient = new DefaultAcsClient(profile);
			// 使用post提交
			request.setMethod(MethodType.POST);
			// 必填:短信签名-可在短信控制台中找到
			request.setSignName("矿脉宝");
			// 必填:短信模板-可在短信控制台中找到

			SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
			return sendSmsResponse;
		} catch (Exception e) {
			throw new KideException(KideExpCode.SMS_ERROR, e.toString());
		}
	}

	public String getCode(String telNo) {
		Page<BizSms> page = new Page<BizSms>(0, 1);
		page.setOrderBy(" create_date desc ");
		BizSms bizSms = new BizSms();

		bizSms.setTelNo(telNo);
		Page<BizSms> bpage = bizSmsService.findPage(page, bizSms);

		if (bpage.getList().size() == 1) {
			BizSms dbBizSms = bpage.getList().get(0);
			Date date = new Date();
			Date createDate = dbBizSms.getCreateDate();
			if ((date.getTime() - createDate.getTime()) < codeTime) {
				return dbBizSms.getCode();
			}
			return null;
		} else {
			return null;
		}
	}

	public static String getCodeRandom() {
		Random random = new Random();
		String fourRandom = random.nextInt(10000) + "";
		int randLength = fourRandom.length();
		if (randLength < 4) {
			for (int i = 1; i <= 4 - randLength; i++)
				fourRandom = "0" + fourRandom;
		}
		return fourRandom;
	}
}
